package com.autonavi.abs.generator.util;

import com.autonavi.abs.generator.common.Constant;
import com.autonavi.abs.generator.common.enumeration.GenerateTypeEnum;
import com.autonavi.abs.generator.common.enumeration.TemplateEnum;
import com.autonavi.abs.generator.common.model.TableMeta;
import com.autonavi.abs.generator.core.property.AppProperty;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import java.io.*;
import java.util.Map;

/**
 * @author tianquan.ld
 * @version V1.0
 * <p>Description: 生成器facade</p>
 * @date 2020-08-10 17:25
 */
@Slf4j
@Component
public class GenerateUtil {

    /**
     * 根据模板信息和数据生成模块文件
     *
     * @param freeMarkerConfigurer
     * @param templateType
     * @param dataMap
     * @throws Exception
     */
    public static void generateModule(FreeMarkerConfigurer freeMarkerConfigurer, TemplateEnum templateType, Map<String, Object> dataMap) throws Exception {

        AppProperty appProperty = (AppProperty) dataMap.get("appProperty");
        String targetPath = getTargetPath(appProperty, templateType);
        File targetPathFile = new File(targetPath);
        if (!targetPathFile.exists()) {
            targetPathFile.mkdirs();
        }

        TableMeta tableMeta = (TableMeta) dataMap.get("tableMeta");

        String pathAndName = getModuleTargetPathAndName(targetPath, templateType, tableMeta.getName());
        File file = new File(pathAndName);

        Template template = getTemplate(freeMarkerConfigurer, templateType.getTemplate());
        FileOutputStream fos = new FileOutputStream(file);

        Writer out = new BufferedWriter(new OutputStreamWriter(fos, Constant.UTF8), Constant.MERGE_FILE_SIZE);
        template.process(dataMap, out);
        out.close();
        fos.close();
    }

    /**
     * 根据模板信息和数据生成应用文件
     *
     * @param freeMarkerConfigurer
     * @param templateType
     * @throws Exception
     */
    public static void generateApp(FreeMarkerConfigurer freeMarkerConfigurer, TemplateEnum templateType, Map<String, Object> dataMap) throws Exception {

        AppProperty appProperty = (AppProperty) dataMap.get("appProperty");
        String targetPath = getTargetPath(appProperty, templateType);
        File targetPathFile = new File(targetPath);
        if (!targetPathFile.exists()) {
            targetPathFile.mkdirs();
        }

        String pathAndName = getAppTargetPathAndName(targetPath, templateType, appProperty);
        File file = new File(pathAndName);

        Template template = getTemplate(freeMarkerConfigurer, templateType.getTemplate());
        FileOutputStream fos = new FileOutputStream(file);

        Writer out = new BufferedWriter(new OutputStreamWriter(fos, Constant.UTF8), Constant.MERGE_FILE_SIZE);
        template.process(dataMap, out);
        out.close();
        fos.close();
    }

    /**
     * 获取目标文件路径
     *
     * @param templateType
     * @param tableName
     * @return
     */
    private static String getModuleTargetPathAndName(String targetPath, TemplateEnum templateType, String tableName) {
        if (templateType.getGenerateType() == GenerateTypeEnum.Module) {
            return targetPath + StringUtil.getFirstUpperCaseFromUnderLine(tableName) + templateType.getTargetSuffix();
        }
        return "";
    }

    /**
     * 获取目标文件路径
     *
     * @param templateType
     * @return
     */
    private static String getAppTargetPathAndName(String targetPath, TemplateEnum templateType, AppProperty appProperty) {
        if (templateType.getGenerateType() == GenerateTypeEnum.App) {
            return targetPath + (templateType.getTargetSuffix().contains("%")
                    ? String.format(templateType.getTargetSuffix(), appProperty.getAppName()) : templateType.getTargetSuffix());
        }
        return "";
    }

    /**
     * 获取模板
     *
     * @param freeMarkerConfigurer
     * @param templatePathAndName
     * @return
     * @throws IOException
     */
    private static Template getTemplate(FreeMarkerConfigurer freeMarkerConfigurer, String templatePathAndName) throws IOException {
        Template template = freeMarkerConfigurer.getConfiguration().getTemplate(templatePathAndName, "UTF-8");
        return template;
    }

    private static String getTargetPath(AppProperty appProperty, TemplateEnum templateEnum) {
        String targetPath = appProperty.getTargetDir() + (templateEnum.getTargetPath().contains("%")
                ? String.format(templateEnum.getTargetPath(), appProperty.getPackageDir()) : templateEnum.getTargetPath());
        return targetPath;
    }

}
